home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / BARNET / COMPILER / SATHER / !Sather / Library / Containrs / sa / h_set < prev    next >
Text File  |  1996-04-09  |  5KB  |  162 lines

  1. ---------------------------> Sather 1.1 source file <--------------------------
  2. -- Author: Benedict A. Gomes <gomes@samosa.ICSI.Berkeley.EDU>
  3. --    Much of the implementation was written by Holger
  4. -- Copyright (C) 1995, International Computer Science Institute
  5. -- $Id: h_set.sa,v 1.6 1996/04/09 10:05:06 borisv Exp $
  6. --
  7. -- COPYRIGHT NOTICE: This code is provided WITHOUT ANY WARRANTY
  8. -- and is subject to the terms of the SATHER LIBRARY GENERAL PUBLIC
  9. -- LICENSE contained in the file: Sather/Doc/License of the
  10. -- Sather distribution. The license is also available from ICSI,
  11. -- 1947 Center St., Suite 600, Berkeley CA 94704, USA.
  12. -------------------------------------------------------------------
  13. class SET{E} < $SET{E} is  include H_SET{E}; end;
  14. -------------------------------------------------------------------
  15. class H_SET{E} < $SET{E} is
  16.     -- Implementation of sets using dynamic hash tables.
  17.     -- This implementation is also available of dealing with equal but
  18.     -- not same objects.
  19.    include SET_INCL{E} create->,size->;
  20.    private include DYNAMIC_BUCKET_TABLE{E,BUCKET{E}} 
  21.      map_copy->copy, create->create;
  22.  
  23.    create_from(a: ARRAY{E}): SAME is
  24.       return create(a);
  25.    end;
  26.  
  27.    create(e: $ELT{E}): SAME is
  28.       res ::= create;
  29.       loop res.insert(e.elt!) end;
  30.       return res;   
  31.    end;
  32.  
  33.    size: INT is return n_inds end;
  34.    
  35.    --              ------ Insertion/Removal --------------- 
  36.    insert(e:E) pre ~void(self) is
  37.       h ::= hash(e);
  38.       loop
  39.      if elt_key_eq(bucket(h).list!.item,e) then return end;
  40.       end;
  41.       set_bucket( h, #BUCKET{E}(e,bucket(h)) );
  42.       n_inds := n_inds + 1;
  43.       update_insert
  44.    end;
  45.  
  46.    delete(e: E) is discard ::= delete(e) end;
  47.  
  48.    clear is
  49.       -- Extremely inefficient.  Must be rewritten by someone who has
  50.       -- looked at the implementation (delete(elt!) may have problems)
  51.       -- Creates a separate list of elements to delete to separte out
  52.       -- iteration from modification
  53.       elts: ARRAY{E} := #(n_inds);
  54.       loop elts.set!(elt!) end;
  55.       loop delete(elts.elt!) end;
  56.    end;
  57.  
  58.    -- The next routines deal with the problem of elements
  59.    -- being equal but not same.
  60.    delete(e:E): E     pre ~void(self) is
  61.       -- Removes an element from the set. Returns the deleted element.
  62.       -- Returns void (or E::nil if E inherits $NIL{E}) if there is
  63.       -- no element to delete.
  64.       h ::= hash(e);
  65.       b ::= bucket(h);
  66.       prev ::= b; prev := void; -- NASTY HACK
  67.       loop until!( void(b) or elt_key_eq(b.item,e) );
  68.      prev := b;
  69.      b := b.next
  70.       end;
  71.       if void(b) then return void end;
  72.       res ::= b.item;
  73.       if void(prev) then set_bucket( h, b.next )
  74.       else  prev.next(b.next) end;
  75.       n_inds := n_inds - 1;
  76.       update_delete;
  77.       return res
  78.    end;
  79.  
  80.    insert_replace(e:E) pre ~void(self) is
  81.       -- Inserts e into the set. If there is already an
  82.       -- element equal to e in the set, the old element
  83.       -- will be replaced.
  84.       dummy ::= insert_replace(e)
  85.     end;
  86.  
  87.     insert_replace(e:E): E   pre ~void(self)  is
  88.       -- Does the same like insert_replace but returns
  89.       -- the old element which is being replaced or the
  90.       -- same object if there was no old one.
  91.       old: E;
  92.       h ::= hash(e);
  93.       firstb ::= bucket(h);
  94.       loop
  95.      b ::= firstb.list!;
  96.      old := b.item;
  97.      if elt_key_eq(old,e) then
  98.         b.item(e);
  99.         return old
  100.      end
  101.       end;
  102.       set_bucket(h,#BUCKET{E}(e,firstb));
  103.       n_inds := n_inds + 1;
  104.       update_insert;
  105.       return e
  106.    end;
  107.  
  108.    --              ------ Access/Measurement --------------
  109.    has(e:E): BOOL pre ~void(self) is
  110.       loop
  111.      if elt_key_eq(bucket(hash(e)).list!.item,e) then return true end;
  112.       end;
  113.       return false;
  114.    end;
  115.  
  116.    get(e:E): E  pre ~void(self) is 
  117.       -- Returns the element equal to 'e' from the set.
  118.       -- Returns void or E::nil if there is no such element.
  119.       -- Self may not be void.
  120.       loop
  121.      i ::= bucket(hash(e)).list!.item;
  122.      if elt_key_eq(i,e) then return i end
  123.       end;
  124.       return elt_key_nil
  125.    end;
  126.  
  127.    union(s: $RO_SET{E}): SAME is
  128.       res ::= copy;
  129.       loop res.insert(s.elt!) end;
  130.       return res;
  131.    end;
  132.    
  133.    intersection(s:$RO_SET{E}): SAME is
  134.       res ::= #SAME;
  135.       loop e ::= elt!; if s.has(e) then res.insert(e) end; end;
  136.       return res;
  137.    end;
  138.  
  139.    diff(s: $RO_SET{E}): SAME is
  140.       res ::= #SAME;
  141.       loop e ::= elt!; if ~s.has(e) then res.insert(e) end; end;
  142.       return res;
  143.    end;
  144.    
  145.    sym_diff(s: $RO_SET{E}): SAME is
  146.       res ::= #SAME;
  147.       loop e ::= elt!; if ~s.has(e) then res.insert(e) end; end;
  148.       loop e ::= s.elt!; if ~has(e) then res.insert(e) end; end;
  149.       return res;
  150.    end;
  151.  
  152.    --              ------ Cursor --------------------------
  153.    elt!: E pre ~void(self) is
  154.       loop
  155.      b ::= bucket( 0.upto!(bound+split_pos-1) );
  156.      loop yield b.list!.item; end
  157.       end
  158.    end;
  159.  
  160. end; -- H_SET{E}
  161. -------------------------------------------------------------------
  162.